//2. new Observer(this._data);
function Observer(data) {
	//3. observe.data = vm._data;
	this.data = data;
	// 4.this.walk(vm._data);
	this.walk(data); //走起
}

Observer.prototype = {
	// 4.this.walk(vm._data);
	walk: function (data) {
		var me = this; //保存Observer实例化对象，因为下面要用
		Object.keys(data).forEach(function (key) {
			me.convert(key, data[key]);
		});
	},
	/*
    	walk: function (vm._data) {
		var me = Observer实例; //保存Observer实例化对象，因为下面要用

		['msg','person'].forEach(function (key) {
			me.convert(key, data[key]);
		});
        ==>>5.
            ob.convert(msg,  "hello mvvm");
            ob.convert(person,  "{name:"xiaoming",msg:"123"}" );
	},
    */
	convert: function (key, val) {
		this.defineReactive(this.data, key, val);
		/* 6.
        this.defineReactive(vm._data, msg,  "hello mvvm");
        this.defineReactive(vm._data, person, "{name:"xiaoming",msg:"123"}" );
        */
	},

	//6. 定义响应式：  this.defineReactive(vm._data, msg,  "hello mvvm");
	defineReactive: function (data, key, val) {
		// 每定义一个响应式就生成一个dep对象
		var dep = new Dep();

		// 递归调用observe,深度劫持
		var childObj = observe(val);

		Object.defineProperty(data, key, {
			enumerable: true, // 可枚举
			configurable: false, // 不能再define
			get: function () {
				if (Dep.target) {
					dep.depend();
				}
				return val;
			},
			set: function (newVal) {
				if (newVal === val) {
					return;
				}
				val = newVal;
				childObj = observe(newVal);
				dep.notify();
			},
		});
		/* 此处劫持重写属性，把原来value改写get,set方法
        Object.defineProperty(vm._data, msg, {
			enumerable: true, // 可枚举
			configurable: false, // 不能再define
			get: function () {
				if (Dep.target) {
					dep.depend();
				}
				return 'hello mvvm';//此处val就是外层的value
			},
			set: function (newVal) {
                // 值不变就退出该函数
				if (newVal === val) {
					return;
				}
                // 将闭包中的value替换为新值
				val = newVal;

                //如果新值得数据类型是一个对象，那么就会对该对象进行深度劫持
                // 被数据劫持过的数据都称为响应式属性
				childObj = observe(newVal);

                // 通知视图更新
				dep.notify();
			},
		}); */
	},
};

//1. 调用observe（this._data,vm）
function observe(value, vm) {
	//2. 排除为值空与非对象
	if (!value || typeof value !== "object") {
		return;
	}
	// 2.new Observer(this._data);
	return new Observer(value);
}

var uid = 0;

function Dep() {
	this.id = uid++;
	this.subs = [];
}

Dep.prototype = {
	addSub: function (sub) {
		this.subs.push(sub);
	},

	depend: function () {
		Dep.target.addDep(this);
	},

	removeSub: function (sub) {
		var index = this.subs.indexOf(sub);
		if (index != -1) {
			this.subs.splice(index, 1);
		}
	},

	notify: function () {
		this.subs.forEach(function (sub) {
			sub.update();
		});
	},
};

Dep.target = null;
